/*
 * ============================================================================
 *
 *       Filename:  ceshi.c
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2014年02月28日 16时38分59秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  jianxi sun (jianxi), ycsunjane@gmail.com
 *   Organization:  
 *
 * ============================================================================
 */
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main()
{
	struct ifreq req;
	int fd_net;
	if( (fd_net = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
		exit(1);
	
	struct ifconf ifc;
	memset(&ifc, 0, sizeof(ifc));
	if( ioctl(fd_net, SIOCGIFCONF, &ifc) < 0)
		exit(1);
	if(ifc.ifc_len <= 0)
		exit(1);
	ifc.ifc_req = (struct ifreq *)malloc(sizeof(ifc.ifc_len));
	if(ifc.ifc_req == NULL)
		exit(1);

	int i,flags;
	ioctl(fd_net, SIOCGIFCONF, &ifc);
	printf("Total interface:%d\n", ifc.ifc_len/sizeof(struct ifreq));
	struct sockaddr_in *ip_v4;
	for(i = 0; i < ifc.ifc_len/sizeof(struct ifreq); i++) {
		printf("ifname:%s, ", ifc.ifc_req[i].ifr_name);
		switch(ifc.ifc_req[i].ifr_addr.sa_family) {
		case AF_INET:
			ip_v4 = (struct sockaddr_in *)&ifc.ifc_req[i].ifr_addr;
			char *str = inet_ntoa(ip_v4->sin_addr);

			strcpy(req.ifr_name, ifc.ifc_req[i].ifr_name);
			ioctl(fd_net, SIOCGIFFLAGS, &req);
			flags = req.ifr_flags;
			ioctl(fd_net, SIOCGIFHWADDR, &req);
			printf("mac: %02x:%02x:%02x:%02x:%02x:%02x\n",
			 (unsigned char) req.ifr_hwaddr.sa_data[0],
			 (unsigned char) req.ifr_hwaddr.sa_data[1],
			 (unsigned char) req.ifr_hwaddr.sa_data[2],
			 (unsigned char) req.ifr_hwaddr.sa_data[3],
			 (unsigned char) req.ifr_hwaddr.sa_data[4],
			 (unsigned char) req.ifr_hwaddr.sa_data[5]);
			printf("sa_family:%s, addr:%s, up:%d, link:%d\n\n", 
				"AF_INET", str, flags & IFF_UP ? 1: 0, 
				flags & IFF_RUNNING ? 1:0);
			break;
		case AF_INET6:
			printf("sa_family:%s,", "AF_INET6");
		default:
			printf("sa_family:%d, ", 
				ifc.ifc_req[i].ifr_addr.sa_family);
			break;
		}
	}
	return 0;
}
